package com.stud.common.annotation.validator;

import com.baomidou.mybatisplus.annotation.TableName;
import com.stud.common.core.domain.BaseEntity;
import com.stud.common.exception.vaidate.StudValidationException;
import com.stud.common.utils.reflect.ReflectUtils;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.SingleColumnRowMapper;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.List;
import java.util.Objects;

/**
 * @author Stud
 * @title XXXXX
 * @desription XXXXX
 * @data 2022-09-05 14:43
 */
@Slf4j
public class StudValidator implements ConstraintValidator<StudValidate, Object> {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    private String[] notRepeats;
    private String message;


    @Override
    public void initialize(StudValidate studValidate) {
        this.notRepeats = studValidate.notRepeats();
        this.message = studValidate.message();
    }

    @Override
    public boolean isValid(Object o, ConstraintValidatorContext constraintValidatorContext) {
        if (!(o instanceof BaseEntity)) {
            throw new StudValidationException("必须继承自BaseEntity");
        }

        if (!o.getClass().isAnnotationPresent(TableName.class)) {
            throw new StudValidationException("必须有TableName注解");
        }

        String tableName = o.getClass().getAnnotation(TableName.class).value();

        for (String fieldName : notRepeats) {
            Long id = ((BaseEntity) o).getId();

            Object fieldValueObj = ReflectUtils.getFieldValue(o, fieldName);
            String fieldValue = String.valueOf(fieldValueObj);

            StringBuilder sb = new StringBuilder(" select count(id) from ");
            sb.append(tableName);
            sb.append(" where ");
            sb.append(ReflectUtils.camelToUnderline(fieldName));
            sb.append(" = '");
            sb.append(fieldValue);
            sb.append("' ");
            if (id != null) {
                sb.append(" and id != ");
                sb.append(id);
            }

            log.debug("校验字段sql==" + sb);

            List<Long> result = jdbcTemplate.query(sb.toString(), new SingleColumnRowMapper<>(Long.class));

            Long count = result.get(0);
            if (count != 0) {
                Schema schema = ReflectUtils.getAccessibleField(o, fieldName).getAnnotation(Schema.class);
                if (Objects.isNull(schema)) {
                    throw new StudValidationException("[" + fieldName + "] " + message + ",不能重复");
                } else {
                    throw new StudValidationException("[" + schema.description() + "] " + message + ",不能重复");
                }
            }
        }
        return ((ValidateInterface) o).validate();
    }

}
